package com.shanshan.dubborpc.netty;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.concurrent.Callable;

/**
 * @Description
 * @ClassName NettyClientHandler
 * @Author 山山大魔王
 * @Date 2022/9/2 14:11
 * @Version 1.0
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable {

    private ChannelHandlerContext context; // 上下文

    private String result; // 返回的结果

    private String para;  // 客户端调用方法时，传入的参数



    /**
     * 与服务器的连接创建后，就会被调用(1)
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelActive被调用");
        context = ctx; // 因为其他方法会使用
    }

    // 收到服务器的数据后，调用方法 (4)
    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("channelRead被调用");
        result = msg.toString();
        notify(); // 唤醒等待线程
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    /**
     * 被代理对象调用，发送数据给服务器， -> wait ->等待被唤醒 ->返回结果 (3)  (5)
     * @return
     * @throws Exception
     */
    @Override
    public synchronized Object call() throws Exception {
        context.writeAndFlush(para);

        wait(); // 等待channelRead方法获取到服务器的结果后，唤醒

        return result;
    }


    public void setPara(String para) { // (2)
        this.para = para;
    }
}
